package com.yalantis.ucrop.util;

import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.app.Environment;
import ohos.media.image.ImagePacker;
import ohos.media.image.PixelMap;

import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import ohos.media.image.ImageSource;

import ohos.agp.utils.Point;

import ohos.media.image.common.Size;
import ohos.utils.net.Uri;
import ohos.agp.window.service.Display;

import com.yalantis.ucrop.callback.BitmapLoadCallback;
import com.yalantis.ucrop.task.BitmapLoadTask;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;


/**
 * Created by Oleksii Shliama (https://github.com/shliama).
 */
public class BitmapLoadUtils {
    private static final String TAG = "BitmapLoadUtils";

    public static void decodeBitmapInBackground(Context context,
                                                Uri uri, Uri outputUri,
                                                int requiredWidth, int requiredHeight,
                                                BitmapLoadCallback loadCallback) {
//原接口
//        new BitmapLoadTask(context, uri, outputUri, requiredWidth, requiredHeight, loadCallback)
//                .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
//版
        new BitmapLoadTask(context, uri, outputUri, requiredWidth, requiredHeight, loadCallback).doInBackground();
    }

    /**
     * transformBitmap
     *
     * @param bitmap bitmap
     * @param degrees degrees
     * @param scale_X scale_X
     * @param context context
     * @return transformBitmap
     */
    public PixelMap transformBitmap(PixelMap bitmap, float degrees, float scale_X, Context context) {
        try {
            //逻辑：对位图使用矩阵进行先旋转再缩放、平移
//            PixelMap converted = PixelMap.create(bitmap, 0, 0, bitmap.getImageInfo().getWidth(), bitmap.getHeight(), transformMatrix, true);
            //逻辑：先保存位图，再读取，读取时旋转和缩放、平移
            File file_path = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File temp_file = new File(file_path + "/temp.jpg");
            _saveImage(temp_file, bitmap);
            Size scaleSize = new Size((int) (bitmap.getImageInfo().size.width*scale_X),bitmap.getImageInfo().size.height);
            PixelMap converted = _loadImage(context, temp_file, scaleSize,degrees);
            if (!bitmap.isSameImage(converted)) {
                bitmap = converted;
            }
        } catch (OutOfMemoryError error) {
            HiLog.error(new HiLogLabel(3,0,"TAG"),"transformBitmap:"+error);
        }
        return bitmap;
    }

    private void _saveImage(File file, PixelMap pixelMap){
        //创建ImagePacker实例
        ImagePacker imagePacker = ImagePacker.create();
        //依据路径创建数据流
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //创建编码设置，并为其添加规则
        ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
        packingOptions.format = "image/jpeg";
        packingOptions.quality = 90;
        //预编码
        imagePacker.initializePacking(outputStream, packingOptions);
        //将需要编码的位图放入ImagePacker中，并完成编码
        imagePacker.addImage(pixelMap);
        imagePacker.finalizePacking();
    }

    /**
     * _loadImage
     *
     * @param context context
     * @param file file
     * @param size size
     * @param degrees degrees
     * @return _loadImage
     */
    public PixelMap _loadImage(Context context, File file, Size size, float degrees) {
        System.out.println(context);
        if (file == null) {
            return null;
        }
        //图片源设置
        ImageSource.SourceOptions options = new ImageSource.SourceOptions();
        options.formatHint = "image/jpg";
        //图片解码设置
        ImageSource.DecodingOptions decodingOptions = new ImageSource.DecodingOptions();
        decodingOptions.desiredSize = size;
        decodingOptions.rotateDegrees = degrees;
        decodingOptions.editable = true;

        //使用ImageSource的create()函数，将图片读取到ImageSource实例中
        ImageSource source = ImageSource.create(file, options);
        //使用ImageSource的createPixelMap()函数，将ImageSource实例解码为位图实例
        return source.createPixelmap(decodingOptions);
    }

    //【风险】暂时没法用
    public static int calculateInSampleSize(Size rawSize, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = rawSize.height;
        final int width = rawSize.width;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width lower or equal to the requested height and width.
            while ((height / inSampleSize) > reqHeight || (width / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    public static int getExifOrientation(Context context, Uri imageUri) {
        //public static final int ORIENTATION_UNDEFINED = 0;
        System.out.println(context);
        int orientation = 0;
        try {
            //通过InputUri获取InputStream
            //InputStream stream = context.getContentResolver().openInputStream(imageUri);
            //通过InputUri获取InputStream
            InputStream stream = null;
            HttpURLConnection connection = null;
            URL url = new URL(String.valueOf(imageUri));
            URLConnection urlConnection = url.openConnection();
            if (urlConnection instanceof HttpURLConnection) {
                connection = (HttpURLConnection) urlConnection;
            }
            if (connection != null) {
                connection.connect();
                // 之后可进行url的其他操作
                // 得到服务器返回过来的流对象
                stream = urlConnection.getInputStream();
            }
            if (stream == null) {
                return orientation;
            }
            orientation = new ImageHeaderParser(stream).getOrientation();
            close(stream);
        } catch (IOException e) {
            HiLog.error(new HiLogLabel(3,0,TAG), "getExifOrientation: " + imageUri.toString()+e);
        }
        return orientation;
    }

    public static int exifToDegrees(int exifOrientation) {
        int rotation;
        switch (exifOrientation) {
            case 6:
            case 5:
                rotation = 90;
                break;
            case 3:
            case 4:
                rotation = 180;
                break;
            case 8:
            case 7:
                rotation = 270;
                break;
            default:
                rotation = 0;
        }
        return rotation;
    }

    public static int exifToTranslation(int exifOrientation) {
        int translation;
        switch (exifOrientation) {
            case 2:
            case 4:
            case 5:
            case 7:
                translation = -1;
                break;
            default:
                translation = 1;
        }
        return translation;
    }

    /**
     * calculateMaxBitmapSize
     *
     * @param context context
     * @return calculateMaxBitmapSize
     * @noinspection checkstyle:JavadocMethod
     */
    public static int calculateMaxBitmapSize(Context context) {
//        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayManager wm = DisplayManager.getInstance();
        Display display;
        int width, height;
        Point size = new Point();

        if (wm != null) {
            display = wm.getDefaultDisplay(context).get();
            display.getRealSize(size);
        }

        width = (int)size.getPointX();
        height = (int)size.getPointY();

        // Twice the device screen diagonal as default
        int maxBitmapSize = (int) Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));

        // Check for max texture size via Canvas
        //无此参数，故预设一个大数
        //final int maxCanvasSize = Math.min(canvas.getMaximumBitmapWidth(), canvas.getMaximumBitmapHeight());
        final int maxCanvasSize = 10000000;
        if (maxCanvasSize > 0) {
            maxBitmapSize = Math.min(maxBitmapSize, maxCanvasSize);
        }

        // Check for max texture size via GL
        final int maxTextureSize = EglUtils.getMaxTextureSize();
        if (maxTextureSize > 0) {
            maxBitmapSize = Math.min(maxBitmapSize, maxTextureSize);
        }

        HiLog.error(new HiLogLabel(3,0,TAG),"maxBitmapSize: " + maxBitmapSize);
        return maxBitmapSize;
    }

    @SuppressWarnings("ConstantConditions")
    public static void close(Closeable c) {
        if (c instanceof Closeable) { // java.lang.IncompatibleClassChangeError: interface not implemented
            try {
                c.close();
            } catch (IOException e) {
                // silence
            }
        }
    }

}